package com.example.api.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.api.dto.JWTToken;
import com.example.api.dto.RegisterReq;
import com.example.api.dto.SigInDto;
import com.example.api.entity.User;
import com.example.api.exception.CustomException;
import com.example.api.service.IUserService;
import com.example.api.util.CaptchaUtil;
import com.example.security.jwt.JwtFilter;
import com.example.security.jwt.TokenProvider;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

import static com.example.api.dto.ResStatusCode.SIGNUP_ERROR;
import static com.example.api.dto.ResStatusCode.SMS_CHECK_ERROR;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author TeacherLi
 * @since 2020-09-06
 */
@RestController
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private IUserService userService;
    @Autowired
    private  PasswordEncoder passwordEncoder;
    @Autowired
    private AuthenticationManagerBuilder managerBuilder;
    @Autowired
    private TokenProvider tokenProvider;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @PostMapping("/signIn")
    @ApiOperation("登录接口")
    public ResponseEntity<JWTToken> signIn(
            @ApiParam("登录Dto")
            @RequestBody(required = true)
            SigInDto sigInDto
    ){

        UsernamePasswordAuthenticationToken authenticationToken=
                new UsernamePasswordAuthenticationToken(sigInDto.getName(),sigInDto.getPassword());

        Authentication authenticate = managerBuilder.getObject()
                .authenticate(authenticationToken);

        SecurityContextHolder.getContext().setAuthentication(authenticate);

        HttpHeaders httpHeaders = new HttpHeaders();
        String token = tokenProvider.createToken(authenticate);

        httpHeaders.add(JwtFilter.AUTHORIZATION_HEADER,"Bearer "+token);

        return new ResponseEntity<>(new JWTToken(token),httpHeaders, HttpStatus.OK);

    }



    @PostMapping("/signUp")
    @ApiOperation("注册")
    public ResponseEntity<JWTToken> signUp(
            @ApiParam("用户注册信息")
            @RequestBody(required = true)
        @Validated
        RegisterReq user
    ){
        //验证短信验证码
        String key = CaptchaUtil.SMS_CAPTCHA_KEY+user.getName();
        String smsCode = redisTemplate.boundValueOps(key).get();
        if(!StringUtils.hasText(smsCode) || !smsCode.equalsIgnoreCase(user.getSmsCode())){
            throw new CustomException(user.getName(), SMS_CHECK_ERROR.getCode(), SMS_CHECK_ERROR.getMessage());
        }
        //是否已经注册
        User userInfo = new User();
        userInfo.setName(user.getName());

        QueryWrapper<User> query = new QueryWrapper<>(userInfo);

        List<User> users = userService.list(query);

        if(!users.isEmpty()){
            throw new CustomException(user.getName(),SIGNUP_ERROR.getCode(),SIGNUP_ERROR.getMessage());
        }

        userInfo.setPassword(passwordEncoder.encode(user.getPassword()));
        userInfo.setPhone(user.getName());
        userInfo.setCreateTime(LocalDateTime.now());
        userInfo.setUpdateTime(LocalDateTime.now());
        userInfo.setDeleted(0);
        userService.save(userInfo);

        //生成Token 返回客户端
        SigInDto signDto= new SigInDto(user.getName(),user.getPassword());
        return signIn(signDto);
    }


    @GetMapping("/getUserInfo")
//    @PreAuthorize("hasAuthority('ROLE_USER')")
      @PreAuthorize("hasRole('USER')")
//    @Secured("ROLE_USER")
//    @RolesAllowed("ROLE_USER")
    public ResponseEntity<User> getUserInfo(){

        Authentication authentication= SecurityContextHolder.getContext().getAuthentication();

        //获取用户名
        String userName = authentication.getName();
        //根据用户名查询用户

        QueryWrapper<User> queryWrapper= new QueryWrapper();
        queryWrapper.eq("name",userName);

        User user = userService.getOne(queryWrapper);
        user.setPassword(null);
        return  ResponseEntity.ok(user);
    }


}
